home *** CD-ROM | disk | FTP | other *** search
- /* Node is a formal class for things that are connected as part
- of a Network. Node defines the connection protocol. Nodes
- know their inputs and outputs, their network and their
- relative display position in the network. */!!
-
- inherit(Object, #Node, #(name /* node name */
- desc /* longer description */
- inputs /* collection of inputs */
- outputs /* collection of outputs */
- network /* who "owns" the node */
- x /* display x position */
- y /* display y position */), 2, nil)!!
-
- now(NodeClass)!!
-
- /* Create and initialize a new node. */
- Def new(self)
- {
- ^init(new(self:Behavior));
- } !!
-
- now(Node)!!
-
- /* Return the network the node belongs to. */
- Def getNetwork(self)
- {
- ^network;
- }!!
-
- /* Return a point of the x and y instance variables. */
- Def pos(self)
- {
- ^point(x, y);
- }!!
-
- /* Get the description. */
- Def getDesc(self)
- { ^desc;
- } !!
-
- /* Get the x position. */
- Def x(self)
- { ^x;
- } !!
-
- /* Get the y position. */
- Def y(self)
- { ^y;
- } !!
-
- /* Reset the position when disconnecting.
- x : the maximum level of any inputs + 1
- y : don't change it since it's already set
- If the x position changes, propogate it.
- Tell the network also.
- */
- Def resetPosn(self, inputNode | oldPos)
- {
- oldPos := pos(self);
- if x <= x(inputNode) + 1
- x := 0;
- do(inputs,
- {using(input) x := max(x(input)+1, x);
- });
- do(outputs,
- {using(output)
- if inputNode <> output cand self <> output /* avoid loop */
- resetPosn(output, self);
- endif;
- });
- endif;
- if x+y = 0 /* completely disconnected */
- y := 1; /* use a "safe" location */
- endif;
- /* the new position could conflict with something else in the project */
- if oldPos <> pos(self)
- resetPosn(network, self, oldPos);
- endif;
- }!!
-
- /* Set the position when connecting.
- x : the maximum level of any inputs + 1
- y : the y of input plus the output number
- If the x position changes, propogate it.
- Also, tell the network.
- */
- Def setPosn(self, inputNode | oldPos)
- {
- oldPos := pos(self);
-
- /* If the node position has not been set, set it's y. */
- if x = 0
- y := max(0,y(inputNode) + size(getOutputs(inputNode)) - 1);
- endif;
-
- /* If the level increases, set it and propogate. */
- if x(inputNode) + 1 > x
- x := x(inputNode) + 1;
- do(outputs,
- {using(output)
- if inputNode <> output cand self <> output /* avoid loop */
- setPosn(output, self);
- endif;
- });
- endif;
- /* the new position could conflict with something else in the project */
- if oldPos <> pos(self)
- resetPosn(network, self, oldPos);
- endif;
- }!!
-
- /* Set the network the node belongs to. */
- Def setNetwork(self, aNet)
- {
- network := aNet;
- }!!
-
- /* To disconnect node n1->n2, n1's outputs must remove n2. */
- Def removeOutputs(self, aNode)
- { remove(outputs, aNode);
- } !!
-
- /* To disconnect node n1->n2, n2's inputs must remove n1. */
- Def removeInputs(self, aNode)
- { remove(inputs, aNode);
- } !!
-
- /* Disconnect n1->n2 by updating n1's outputs and n2's inputs.
- The node n2 position must be reset based on its former input. */
- Def disconnect(self, aNode)
- { removeInputs(aNode, self);
- removeOutputs(self, aNode);
- resetPosn(aNode, self);
- } !!
-
- /* Recursively show all outputs, level by level.
- Keep track of visited nodes to avoid looping.
- n is the level for formatting. CurPos is a
- global of current print position for formatting.
- Note: This is for testing networks during development.
- */
- Def show(self, visited, n)
- {
- do(n-CurPos, /* adjust position */
- {using(i) print(" ");
- });
- CurPos:=n; /* update position */
- print(self); /* show node */
- if size(outputs) == 0 then
- printLine("");print(" ");
- CurPos := 0;
- else
- CurPos := CurPos +1;
- endif;
- do(outputs, /* show outputs */
- {using(elem)
- if(not(elem in visited)) /* not yet shown */
- add(visited, elem); /* avoid looping */
- show(elem, visited, n+1); /* recurse */
- else
- printLine("");
- print(" ");
- CurPos := 0; /* reset position */
- endif;
- });
- } !!
-
- /* pass through method to return a node's outputs */
- Def getOutputs(self)
- { ^outputs;
- } !!
-
- /* pass through method to return a node's inputs */
- Def getInputs(self)
- { ^inputs;
- } !!
-
- /* To connect node n1->n2, n1's outputs must contain n2. */
- Def addOutputs(self, aNode)
- {
- add(outputs, aNode);
- } !!
-
- /* To connect n1->n2, n2's inputs must contain n1. */
- Def addInputs(self, aNode)
- {
- add(inputs, aNode);
- } !!
-
- /* Connect self->aNode by updating self's outputs and
- aNode's inputs. Also, aNode should know it's network
- and the position should be set based on it's input. */
- Def connect(self, aNode)
- { addInputs(aNode, self);
- addOutputs(self, aNode);
- setNetwork(aNode, network);
- setPosn(aNode, self);
- } !!
-
- /* Set the name. */
- Def setName(self, aName)
- { name := aName;
- } !!
-
- /* Get the name. */
- Def getName(self)
- { ^name;
- } !!
-
- /* Initialize a new node. Set the name, desc
- and position to safe values. Keep track of
- our connections in inputs and outputs. These
- sets will grow as necessary. */
- Def init(self)
- { name := desc:= "";
- x := y := 0;
- inputs := new(Set, 2);
- outputs := new(Set, 2);
- } !!
-
- /* Print the node.
- This is used during development only. */
- Def printOn(self, aStrm)
- {
- printOn(asString(class(self))+":"+asString(name), aStrm);
- }!!
-
-